#pragma once
#ifndef PROCTABLE_H
#define PROCTABLE_H

#include "spa_types.h"
#include <string>
#include <map>

using namespace std;

class ProcTable
{

public:

	ProcTable();
	~ProcTable();

	/*
	 Returns:
		Added successully:	Return the proc's index.
		Already exist:		Return the proc's index.
		Invalid proc name:	Return -1;
	*/
	PROCINDEX InsertProc(const STRING proc_name);
	void SetProcStatementRange(const PROCINDEX index, const INTEGER first_statement_number, const INTEGER last_statement_number);
	INTEGER GetProcFirstStatementNumber(const PROCINDEX index);
	INTEGER GetProcLastStatementNumber(const PROCINDEX index);
	
	/*
	 Returns:
		Procedure name if proc index exists in ProcTable.
		Empty STRING if proc index does not exist.
	*/
	STRING GetProcName(const PROCINDEX index);
	
	/*
	 Returns:
		PROCINDEX if procedure exists in ProcTable.
		-1 if procedure does not exist.
	*/
	PROCINDEX GetProcIndex(const STRING proc_name);


	/********************************
	      New APIs for ProcTable
	*********************************/

	/*
	 Returns:
		The set of proc indices is returned if there are procedures in ProcTable.
		The empty set, ie. size() == 0 if are no procedures in ProcTable.
	*/
	PROCINDEX_ARRAY GetAllProcIndex();
	
	/*
	 Returns:
		PROCINDEX which the given statement number resides within (inclusive).
		-1 if statement number is not found within any proc's statement ranges.
	*/
	PROCINDEX GetProcIndex(const INTEGER statement_number);

	/*
	 Returns:
	   No variables:	An empty STRING_ARRAY if there are nothing found, i.e. size() == 0
	   Have variables:	STRING_ARRAY containing all the names of the variables.
	*/
	STRING_ARRAY GetAllProcNames();

	/*
	 Returns:
	   Number of procedures in ProcTable
	*/
	INTEGER GetProcCount();

private:
		
	/*
	 There may be more information we would want to keep about a procedure.
	 For example, its name, first stmt num, last stmt num, etc.
	*/
	struct ProcInfo 
	{
		PROCINDEX proc_index;
		STRING proc_name;
		INTEGER first_statement_number;
		INTEGER last_statement_number;
	};
	
	/*
	 Will start from index 0.
	 Use this for the index of the next procedure insertion.
	*/
	int curr_index;
	PROCINDEX_ARRAY proc_index_array;

	map<PROCINDEX, ProcInfo*> index_table;
	map<STRING, ProcInfo*> name_table;
};

#endif